Skip to content

fix(byok): support user OpenAI/Anthropic API keys + working effort pill#25

Merged
OmGuptaIND merged 2 commits into
mainfrom
OmGuptaIND/byok-models-fix
May 4, 2026
Merged

fix(byok): support user OpenAI/Anthropic API keys + working effort pill#25
OmGuptaIND merged 2 commits into
mainfrom
OmGuptaIND/byok-models-fix

Conversation

@OmGuptaIND
Copy link
Copy Markdown
Contributor

Summary

Three connected bugs that surfaced when a user supplies their own OpenAI/Anthropic key (BYOK) instead of using the Anton/OpenRouter proxy:

  1. resolveModel rejected BYOK models. Only anton and openrouter had fallbacks — direct-API providers (openai, anthropic, google, groq, mistral) relied entirely on pi SDK's hardcoded registry, so any model the registry didn't know (e.g. gpt-5.5) failed to start a session. New buildDirectApiModel mirrors buildOpenRouterModel for these providers and routes to the right api/baseUrl. resolveModel now also threads an optional baseUrl override so users with self-hosted/proxy endpoints work.

  2. Mid-conversation switchModel was brittle. It called pi SDK's setModel but didn't reconcile the rest of the model-derived state. Hardened to (a) fail fast with a clear error when the new provider has no API key, (b) clamp thinking level to 'off' on reasoning → non-reasoning transitions so the upstream API doesn't reject the request, (c) refresh compactionConfig.maxContextTokens so the gauge and compaction threshold match the new model's window.

  3. Effort pill was hidden for API sessions on gpt-5.x. Pi SDK and the server-side wiring were already correct — Session.setThinkingLevel forwards to piAgent.setThinkingLevel. The composer's supportsReasoningEffort() regex just didn't include the gpt-5 family. Worked for the codex harness because that branch returns true unconditionally. Regex now matches the same families buildDirectApiModel detects, with a comment pointing the two heuristics at each other so they don't drift.

Test plan

  • Add an OpenAI API key in Provider settings, pick gpt-5.5, send a message → session starts, response streams.
  • Add an Anthropic API key, pick claude-sonnet-4-6, send a message → works.
  • Mid-conversation, switch from claude-opus-4-6 (reasoning) → a non-reasoning model → next turn doesn't get rejected for sending a thinkingLevel.
  • Mid-conversation, switch to a provider with no key configured → clear error in the log; other sessions keep working.
  • With provider=openai, model=gpt-5.5 selected, the Effort pill is visible in the composer and changes the next turn's effort.
  • With provider=codex (harness), the Effort pill still shows.
  • With provider=claude (Claude Code harness), the Effort pill stays hidden (CLI has no thinking flag).

🤖 Generated with Claude Code

OmGuptaIND and others added 2 commits May 4, 2026 16:57
Three connected bugs that surfaced when a user supplied their own
OpenAI/Anthropic key (BYOK) instead of using the Anton/OpenRouter proxy.

1. resolveModel only had fallbacks for `anton` and `openrouter`. For
   direct-API providers (openai, anthropic, google, groq, mistral) it
   relied entirely on pi SDK's hardcoded registry, so any model the
   registry didn't know about (e.g. `gpt-5.5`) failed to start a session.
   New `buildDirectApiModel` builder mirrors `buildOpenRouterModel` for
   these providers and routes to the right `api`/`baseUrl`. resolveModel
   now also threads an optional baseUrl override so users with
   self-hosted/proxy endpoints work.

2. Mid-conversation `switchModel` was brittle: it called pi SDK's
   `setModel` but didn't reconcile the rest of the session's
   model-derived state. Hardened it to (a) fail fast with a clear error
   when the new provider has no API key, (b) clamp thinking level to
   'off' on reasoning -> non-reasoning transitions so the upstream API
   doesn't reject the request, (c) refresh
   compactionConfig.maxContextTokens so the gauge and compaction
   threshold match the new model's window.

3. The composer's Effort pill was hidden for API sessions on `gpt-5.x`
   because `supportsReasoningEffort()`'s regex didn't include the gpt-5
   family. Worked for the `codex` harness because that branch returns
   true unconditionally. Pi SDK and the server-side wiring were already
   correct; only the UI gate needed the fix. Regex now matches the same
   families `buildDirectApiModel` detects, with a comment pointing the
   two heuristics at each other so they don't drift.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Place pending-confirm prompts immediately above the composer (inside
`conv-dock__inner`) instead of higher in the chat shell, so the dialog
sits where the user is already looking. Adjust `.chat-shell__confirm`
spacing to match the new placement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@OmGuptaIND OmGuptaIND merged commit c178ae0 into main May 4, 2026
OmGuptaIND added a commit that referenced this pull request May 4, 2026
### Other
- fix(byok): support user OpenAI/Anthropic API keys + working effort pill (#25)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant